Skip to content

WIP [dbnode] Buffer encoded commit log data and finalize batch resources async#2395

Open
robskillington wants to merge 6 commits into
masterfrom
r/commitlog-finalize-batch-async
Open

WIP [dbnode] Buffer encoded commit log data and finalize batch resources async#2395
robskillington wants to merge 6 commits into
masterfrom
r/commitlog-finalize-batch-async

Conversation

@robskillington
Copy link
Copy Markdown
Collaborator

What this PR does / why we need it:

Allows pending IO to queue up while encode loop for the commit log can continue working.

Also reserves an entire gomaxproc for encode loop to avoid scheduling latency/being pre-empted while in the middle of critical encode loop.

Special notes for your reviewer:

Does this PR introduce a user-facing and/or backwards incompatible change?:

NONE

Does this PR require updating code package or user-facing documentation?:

NONE

writer := newMockCommitLogWriter()

writer.writeFn = func(ts.Series, ts.Datapoint, xtime.Unit, ts.Annotation) error {
writer.writeFn = func(ts.Series, ts.Datapoint, xtime.Unit, ts.Annotation, callbackFn) error {
Copy link
Copy Markdown
Collaborator

@arnikola arnikola Jun 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow you can do this? I thought you needed to explicitly set the args as _ callbackFn etc

// double calling callback.
var callback callbackFn
if i == lastWritableElem {
callback = write.callbackFn
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be useful adding a metric here to see how often this hits?

numWritesSuccess++
}
if lastWritableElem == -1 && write.callbackFn != nil {
// Call callback successfully if no elements actually needed to write.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be useful adding a metric here to see how often this hits?

// goroutines since write latency is very important.
// For
if numCPU := runtime.NumCPU(); numCPU <= 16 {
runtime.GOMAXPROCS(runtime.NumCPU() + 1)
Copy link
Copy Markdown
Collaborator

@arnikola arnikola Jun 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: numCPU + 1

lastWritableElem := -1
for i := numDequeued - 1; i >= 0 && lastWritableElem == -1; i-- {
if batch[i].Err == nil && !batch[i].SkipWrite {
lastWritableElem = i
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can this break instead of having lastWritableElem == -1 in the guard? makes intentions clearer, and one fewer check per iteration is a bonus

return r.rotateLogs, nil
}

func zeroToTenSecondsHighResDurationBuckets() tally.Buckets {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a lot of buckets, any concerns for cardinality / instrumentation perf here?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm actually looks like the other buckets we have is ~60 so this is probably fine

for i := 1; i <= 10; i++ {
buckets = append(buckets, time.Duration(i)*time.Second)
}
return buckets
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a +Inf upper bound value here?

}
b.flushCalls <- call

next := b.idx + 1
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: b.idx = (b.idx+1)%len(b.writers)? Or is len(b.writers) potentially 0

pLen := len(p)
currLen := len(b.writers[b.idx].buffer)
newLen := currLen + pLen
if currLen > 0 && newLen > b.singleBufferLength {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any chance newLen > b.singleBufferlength * 2? Maybe this needs to be a for loop? Similarly if just len(p) is greater than a single buffer size

writers []asyncFlushBufferWriter
total int
)
for total+opts.singleBufferLength <= opts.totalBufferLength {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit; can just use regular for here for total := 0 ; total < opts.totalBufferLength; total += opts.singleBufferLength {?

Comment on lines +127 to +129
if 2*flushSize > flushBufferSize {
flushBufferSize = 2 * flushSize
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Can we refactor FlushBufferSize to be something like NumBuffers or something to keep it a multiple of a single buffer size? Then Validate() can ensure FlushBufferSize > 2

@codecov
Copy link
Copy Markdown

codecov Bot commented Sep 11, 2023

Codecov Report

❌ Patch coverage is 85.79235% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.6%. Comparing base (b239df4) to head (c4a34a3).
⚠️ Report is 1430 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           master   #2395     +/-   ##
========================================
- Coverage    71.7%   71.6%   -0.1%     
========================================
  Files        1052    1051      -1     
  Lines       93115   92958    -157     
========================================
- Hits        66797   66613    -184     
- Misses      21874   21894     +20     
- Partials     4444    4451      +7     
Flag Coverage Δ
aggregator 76.4% <ø> (-0.1%) ⬇️
cluster 84.8% <ø> (ø)
collector 82.8% <ø> (ø)
dbnode 79.1% <85.7%> (-0.1%) ⬇️
m3em 74.4% <ø> (ø)
m3ninx 73.1% <ø> (+<0.1%) ⬆️
m3nsch 51.1% <ø> (ø)
metrics 17.3% <ø> (ø)
msg 75.2% <ø> (+0.1%) ⬆️
query 67.9% <ø> (-0.4%) ⬇️
x 81.8% <ø> (-0.3%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b239df4...c4a34a3. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants